﻿namespace NorthernLights.Controls.Tools
{
    using System;
    using System.Windows.Input;

    /// <summary>
    /// Represents a <see cref="NotificationTool"/> user action.
    /// </summary>
    public class NotificationAction
    {
        #region Constructors
        /// <summary>
        /// Initializes a new instance of the NotificationAction class.
        /// </summary>
        /// <param name="content">The content to display.</param>
        /// <param name="execute">The action to execute.</param>
        public NotificationAction(object content, Action execute)
            : this(content, null, execute, () => true)
        {
        }

        /// <summary>
        /// Initializes a new instance of the NotificationAction class.
        /// </summary>
        /// <param name="content">The content to display.</param>
        /// <param name="execute">The action to execute.</param>
        /// <param name="canExecute">The function to determine if command can be executed.</param>
        public NotificationAction(object content, Action execute, Func<bool> canExecute)
            : this(content, null, execute, canExecute)
        {
        }

        /// <summary>
        /// Initializes a new instance of the NotificationAction class.
        /// </summary>
        /// <param name="content">The content to display.</param>
        /// <param name="contentTemplateKey">The content template to display.</param>
        /// <param name="execute">The action to execute.</param>
        public NotificationAction(object content, object contentTemplateKey, Action execute)
            : this(content, contentTemplateKey, execute, () => true)
        {
        }

        /// <summary>
        /// Initializes a new instance of the NotificationAction class.
        /// </summary>
        /// <param name="content">The content to display.</param>
        /// <param name="contentTemplateKey">The content template to display.</param>
        /// <param name="execute">The action to execute.</param>
        /// <param name="canExecute">The function to determine if command can be executed.</param>
        public NotificationAction(object content, object contentTemplateKey, Action execute, Func<bool> canExecute)
        {
            this.Content = content;
            this.ContentTemplateKey = contentTemplateKey;
            this.Command = new NotificationCommand(execute, canExecute);
        }
        #endregion

        #region Properties
        /// <summary>
        /// Gets the Content object.
        /// </summary>
        public object Content { get; private set; }

        /// <summary>
        /// Gets the ContentTemplateKey object.
        /// </summary>
        public object ContentTemplateKey { get; private set; }

        /// <summary>
        /// Gets the Command.
        /// </summary>
        internal ICommand Command
        {
            get;
            private set;
        }
        #endregion

        #region NotificationCommand
        /// <summary>
        /// NotificationCommand class.
        /// </summary>
        private class NotificationCommand : ICommand
        {
            #region Fields
            private readonly Action execute;
            private readonly Func<bool> canExecute;
            #endregion

            #region Constructor
            /// <summary>
            /// Initializes a new instance of the NotificationCommand class.
            /// </summary>
            /// <param name="execute">The action to execute.</param>
            /// <param name="canExecute">The fucntion to determine is action can be executed.</param>
            public NotificationCommand(Action execute, Func<bool> canExecute)
            {
                this.execute = execute;
                this.canExecute = canExecute;
            }
            #endregion

            #region Events
            event EventHandler ICommand.CanExecuteChanged
            {
                add { }
                remove { }
            }
            #endregion

            #region Public methods
            /// <summary>
            /// Returns if command can be executed.
            /// </summary>
            /// <param name="parameter">Parameter not used.</param>
            /// <returns>True if command can be executed.</returns>
            bool ICommand.CanExecute(object parameter)
            {
                if (this.canExecute != null)
                {
                    return this.canExecute();
                }
                else
                {
                    return false;
                }
            }

            /// <summary>
            /// Execute command.
            /// </summary>
            /// <param name="parameter">Parameter not used.</param>
            void ICommand.Execute(object parameter)
            {
                if (this.execute != null)
                {
                    this.execute();
                }

                NotificationTool.Close();
            }
            #endregion
        }
        #endregion
    }
}
